<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />

  <!-- Use the .htaccess and remove these lines to avoid edge case issues.
       More info: h5bp.com/b/378 -->
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />

  <title>Video Downloader</title>
  <meta name="description" content="Video downloader demo" />
  <meta name="author" content="Roger Xu" />

  <!-- Mobile viewport optimized: h5bp.com/viewport -->
  <meta name="viewport" content="width=device-width,initial-scale=1" />

  <!-- Place favicon.ico and apple-touch-icon.png in the root directory: mathiasbynens.be/notes/touch-icons -->

  <link rel="stylesheet" href="../css/style.css" />
  <link rel="stylesheet" href="../script/libs/jquery-ui/themes/base/jquery.ui.all.css" />

  <!-- All JavaScript at the bottom, except this Modernizr build incl. Respond.js
       Respond is a polyfill for min/max-width media queries. Modernizr enables HTML5 elements & feature detects;
       for optimal performance, create your own custom Modernizr build: www.modernizr.com/download/ -->
  <script src="../script/libs/modernizr-2.0.6.min.js"></script>
</head>

<body>
  <div id="container">
    <header>
      <hgroup>
        <h1>Video Downloader</h1>
        <h2 id="version">Unknown Version</h2>
      </hgroup>

      <nav>
        <ul>
          <li><a href="#">Home</a></li>
          <li><a href="#">About</a></li>
          <li><a href="#">Services</a></li>
          <li><a href="#">Contact</a></li>
        </ul>
      </nav>
    </header>
    <div id="main" role="main">
      <p>God helps those who help themselves.</p>
      <div>
        <form id="queryForm" method="get">
          <p>
            <input id="isSourceMode" type="checkbox" name="sourceMode" value="true" /> <label for="isSourceMode">Paste source</label>
          </p>
          <p id="urlMode">
            <label for="urlField">URL:</label> <input id="urlField" name="url" style="width: 50em;"/><br />
          </p>
          <p id="sourceMode">
            <label for="sourceField">Source:</label> <textarea id="sourceField" name="source" rows="20" cols="100"></textarea>
          </p>
          <p>
            <input id="submitButton" type="submit" value="Submit" />
            <input id="resetButton" type="reset" value="Reset" />
          </p>
        </form>
      </div>
      <div id="linkBar"></div>
    </div>
    <footer>
      <p>copyright &copy; 2011</p>
    </footer>
  </div> <!--! end of #container -->

  <!-- JavaScript at the bottom for fast page loading -->

  <script src="../script/libs/jquery-1.7.1.js"></script>
  <script>window.jQuery || document.write('<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"><\/script>')</script>
  <script src="../script/libs/jquery-ui-1.8.16.js"></script>
  <script>window.jQuery.ui || document.write('<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"><\/script>')</script>
  <script src="../script/libs/json2.js"></script>
  <script src="../script/libs/jsrender.js"></script>

  <!-- scripts concatenated and minified via ant build script-->
  <script defer src="../script/plugins.js"></script>
  <!-- end scripts-->

  <script>
    function substringBetween(str, open, close) {
        var INDEX_NOT_FOUND = -1;

        if (str == null || open == null || close == null) {
            return null;
        }
        var start = str.indexOf(open);
        if (start !== INDEX_NOT_FOUND) {
            var end = str.indexOf(close, start + open.length);
            if (end !== INDEX_NOT_FOUND) {
                return str.slice(start + open.length, end);
            }
        }
        return null;
    }

    function escapeHtml(input) {
        return $('<div/>').text(input).html();
    }
    function unescapeHtml(input) { 
        return $('<div/>').html(input).text();
    }

    var VideoFormat = {
        Unknown: -1,
        _3GP_LOW: 13,
        _3GP_MED: 17,
        WebM_360P: 43,
        WebM_480P: 44,
        WebM_720P: 45,
        WebM_1080P: 46
    };
  </script>
  <script>
    $(document).ready(function() {
        // version
        var version = $.fn.jquery;
        $('#version').html('jQuery: ' + version);

        // form handler
        $('#queryForm').submit(function() {
            var stream = null;
            var isSourceMode = $('#isSourceMode').is(':checked');

            if (isSourceMode) {
                var pageSource = $('#sourceField').val(); 
                stream = parseSource(pageSource);
            } else {
                stream = {};
                stream.url = $.trim($('#urlField').val());
            }

            if (stream) {
                createLink(stream);
            }

            return false;
        });

        // checkbox handler
        $('#isSourceMode').click(function() {
            var isSourceMode = $(this).is(':checked');
            $('#sourceMode').toggle(isSourceMode);
            $('#urlMode').toggle(!isSourceMode);
        });

        // hide source mode on page loaded
        $('#sourceMode').toggle(false);

        // test
        $('#urlField').val('http://www.youtube.com/watch?v=B_vdL1JxclI');
    });

    function parseSource(pageSource) {
        var stream = {};
        var url = null;

        var videoId = substringBetween(pageSource, 'shortlink" href="http://youtu.be/', '"');
        var videoTitle = substringBetween(pageSource, "'VIDEO_TITLE': '", "',");
        if (!videoTitle) {
            videoTitle = substringBetween(pageSource, 'name="title" content="', '"');
        }
        var title = unescapeHtml(videoTitle);
        var titleParam = encodeURIComponent(title);

        var fmtStreamMap = substringBetween(pageSource, 'fmt_stream_map=', 'amp;');
        if (fmtStreamMap) {
            fmtStreamMap = decodeURIComponent(fmtStreamMap);
        } else {
            fmtStreamMap = substringBetween(pageSource, 'fmt_stream_map": "', '"');
        }

        var fmtStreamEntries = fmtStreamMap.split(',');
        var fmtStreams = [];

        $.each(fmtStreamEntries, function(index, fmtStreamEntry) { 
            var fmtStreamUrl = fmtStreamEntry.slice('url='.length);
            fmtStreamUrl = decodeURIComponent(fmtStreamUrl);
            var clipUrl = fmtStreamUrl.slice(0, fmtStreamUrl.indexOf('&type=')); // &type=
            clipUrl = clipUrl + '&title=' + titleParam;
            var fmtStream = {
                url: clipUrl
            };

            var matches = clipUrl.match(/&itag=(\d+)/);
            if (matches.length > 1) {
                var fmtId = matches[1] || -1;
                var fmtName = 'Unknown';
                for (var key in VideoFormat) {
                    if (fmtId === ('' + VideoFormat[key])) {
                        fmtName = key;
                        break;
                    }
                }

                console.debug('fmt:', fmtName);
                fmtStream.fmt = fmtName;
                fmtStream.fmtId = parseInt(fmtId);
            }
            fmtStreams.push(fmtStream);
        });

        console.info(fmtStreams);
        var bestStream = null;
        $.each(fmtStreams, function(index, fmtStream) {
            if (fmtStream.fmtId === VideoFormat.WebM_1080P) {
                bestStream = fmtStream;
                return false;
            }
            if (fmtStream.fmtId === VideoFormat.WebM_720P) {
                bestStream = fmtStream;
                return false;
            }
            if (fmtStream.fmtId ===  VideoFormat.WebM_480P) {
                bestStream = fmtStream;
                return false;
            }
            if (fmtStream.fmtId ===  VideoFormat.WebM_360P) {
                bestStream = fmtStream;
                return false;
            }
        });
        
        stream.fmt = bestStream ? bestStream.fmt : null;
        stream.url = bestStream ? bestStream.url : fmtStreams[0].url;
        return stream;
    }

    function createLink(stream) {
        var url = stream.url;
        var template = '<a href="{0}" target="_blank">{1}</a><br />';
        var linkHtml = template.replace(/\{0\}/g, url);

        // title
        var matches = url.match(/&title=(.+)/);
        if (matches.length > 1) {
            var title = matches[1];
            title = decodeURIComponent(title);
            console.debug('title:', title);
            if (stream.fmt) {
                title += ' [' + stream.fmt + ']';
            }
            linkHtml = linkHtml.replace(/\{1\}/g, title);
        }

        $('#linkBar').append(linkHtml);
    }
  </script>
</body>
</html>